Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format all numbers with BigNumber #333

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

csillag
Copy link
Contributor

@csillag csillag commented Apr 25, 2023

Not handled:

  • Currency amounts
  • Percentages
  • Anything inside EVM logs (will handle in separate PR)
  • Labels on the Y axis of line charts

@github-actions
Copy link

github-actions bot commented Apr 25, 2023

Deployed to Cloudflare Pages

Latest commit: 84a2c500063e0bb184c68340d49e72bb70115a9b
Status:✅ Deploy successful!
Preview URL: https://1258fbc2.oasis-explorer.pages.dev

@csillag csillag force-pushed the csillag/number-formatting branch 3 times, most recently from 71769f8 to 9be2492 Compare April 26, 2023 15:08
@csillag csillag marked this pull request as ready for review April 26, 2023 15:12
@csillag csillag force-pushed the csillag/number-formatting branch 3 times, most recently from 6273034 to 303e647 Compare May 1, 2023 17:24
@csillag csillag requested review from lukaw3d, buberdds and lubej May 1, 2023 17:24
src/app/components/Account/index.tsx Outdated Show resolved Hide resolved
src/locales/en/translation.json Outdated Show resolved Hide resolved
const { decimalPlaces, maximumFractionDigits, roundingMode, unit, ...formatting } = format
let number =
typeof inputNumber === 'number'
? BigNumber(inputNumber.toString(2), 2) // This is required to keep all precision
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this comment. How

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read this and this together.

If the limited precision of Number values is not well understood, it is recommended to create BigNumbers from String values rather than Number values to avoid a potential loss of precision.

When creating a BigNumber from a Number, note that a BigNumber is created from a Number's decimal toString() value not from its underlying binary value. If the latter is required, then pass the Number's toString(2) value and specify base 2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, to summarize: according to the docs, in order to get all the data from a Number, with no loss of precision, we need to create a binary string representation. Otherwise it will just create a string (with whatever precision) and that will be the input of BigNumber.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay it loses precision differently

BigNumber((10000000000/3).toString(2), 2).toFixed()
'3333333333.33333349227905273438'

BigNumber(10000000000/3).toFixed()
'3333333333.3333335'

src/app/utils/numberFormatter.ts Outdated Show resolved Hide resolved
src/app/utils/numberFormatter.ts Outdated Show resolved Hide resolved
@csillag csillag requested a review from lukaw3d May 2, 2023 10:51
@csillag
Copy link
Contributor Author

csillag commented May 2, 2023

Finished reacting to the first round of comments. Ready for second round.

@csillag
Copy link
Contributor Author

csillag commented May 2, 2023

Fixing the broken test case...

Comment on lines 49 to 55
if (number.toNumber() === 1) {
return t(countKey as any, { count: 1 })
} else {
return t(countKey as any, { count: 2 }).replace('2', numberString)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't pluralize well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I have a new solution now, which should take care of it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new solution is

const i18nForm = t('common.number', { value: num })
return t(countKey as any, { count: num }).replace(i18nForm, numberString)

I've been thinking if there are any solutions that don't involve string manipulation, and I have one:

return t(countKey as any, {
  count: number.toNumber(), // To pluralize the translation strings
  value: numberString, // To display in translation strings (without losing precision, and with consistent formatting)
})

? BigNumber(inputNumber.toString(2), 2) // This is required to keep all precision
: BigNumber(inputNumber)
if (maximumFractionDigits !== undefined) {
number = BigNumber(number.toFixed(maximumFractionDigits, roundingMode))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how come not number.decimalPlaces

Comment on lines +33 to +38
const numberString =
decimalPlaces === undefined
? number.toFormat(wantedFormat)
: roundingMode === undefined
? number.toFormat(decimalPlaces, wantedFormat)
: number.toFormat(decimalPlaces, roundingMode, wantedFormat)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If bignumber types weren't broken I would modify to:

  return (
    inputNumber: number | string | BigNumber.Instance | undefined,
    format: NumberFormattingParameters = { roundingMode: BigNumber.ROUND_DOWN },
  ): string | undefined => {
  
    const numberString = number.toFormat(decimalPlaces, roundingMode, wantedFormat)

if (num === 1) {
return t(countKey as any, { count: 1 })
} else {
const i18nForm = t('common.number', { value: num })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#731 (comment)
We might be able to simplify a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants